/**
 * @description 封装异步请求库
 */
 import router from '@/router'
 import store from '@/store'
 import axios from 'axios'
 
 let AxiosInstance = axios.create({
     baseURL: '/seeyon',
     timeout: 30000
 })
 
 /**
  * 可以通过请求前的拦截实现--baseURL参数修改、实现请求头token注入、也可以实现token拦截(它是登录标识，那么如果一个用户连token都没有，那么不可以调用获取用户信息等这样的业务接口--实现请求权限拦截)
  * request是请求还没有发出去的拦截
  * use(onFulfilled?: (value: V) => V) use方法要求我们传递一个回调函数进去，然后函数有一个形参进来，要求我们返回一个传递进来的参数
  */
 /**
  * 可以配置一个对象，这个对象的key就是代理地址，然后值为需要进行代理的url地址
  */
 let proxyObj = {
     '/wangxiang': [
         "/city/list"
     ],
 }
 /**
  * 可以实现token通用注入控制，有些地址不要token，有些必须有token并且要注入
  * token在哪里？--vuex里边
  */
 let noTokenUrl = [
     '/login', '/user/validate/code', '/user/app/login', "/city/list"
 ]
 AxiosInstance.interceptors.request.use(function(config) {
     // if (config.url === "/city/list") {
     //     config.baseURL = '/wangxiang'
     // }
     for (let name in proxyObj) {
         let it = proxyObj[name]
         if (it.includes(config.url)) {
             config.baseURL = name
             break
         }
     }
 
     // 实现token拦截和注入
     if (noTokenUrl.includes(config.url)) {
         return config
     } else {
         // 判断token是否存在，如果不存在--那么请求需要中断--因为axios是基于Promise封装的，所以可以返回一个错误的Promise(Promise.reject())就可以中断请求
         let token = store.getters['common/token']
         if (!token) {
             return Promise.reject({code: 0, message: '前端没有token数据，你没有缓存'})
         } else {
             config.headers.token = token
             return config
         }
     }
 })
 
 /**
  * 响应拦截--对于跳过前端拦截，然后进行的响应处理
  * 可以实现token失效处理、验证请求是否安全
  * use(onFulfilled?: (value: AxiosResponse) => AxiosResponse | Promise)
  * use方法要求传递一个参数(数据类型为一个函数A)进去，函数A会入参一个响应对象B，可以对响应对象B进行处理，然后函数A要求返回一个响应对象B或则一个Promise对象
  */
 AxiosInstance.interceptors.response.use(response => {
     let {data} = response
     if (data.code === 403 && data.message === "Request information authentication failed.") {
         alert('用户非法请求，请重新登录')
         router.push('/login')
         return Promise.reject({code: 400, message: '用户非法请求，请重新登录'})
     } else {
         return response
     }
 })
 
 /**
  * 异步请求方法
  * @param {string | {url: string,data: any, params: any, method: 'POST' | 'GET' | 'DELETE' | 'PUT' | 'PATCH'}} req 
  * @returns 
  */
 function ajax(req) {
     if (!req) throw new TypeError('请求参数必传')
     if (!!req.startsWith) {
         req = {url: req}
     }
     if (!req.url) throw new TypeError('url参数必传')
     // async + await 只能处理Promise.resolve（then结果）
     return new Promise(resolve => {
         AxiosInstance.request({
             url: req.url,
             method: req.method || 'POST',
             // 它是查询参数--链接在url地址传递的参数
             params: req.params || {},
             // 请求体参数
             data: req.data || {}
         }).then(({ data }) => {
             resolve(data)
         }).catch(e => {
             resolve(e)
         })
     })
 }
 
 export default ajax